/**
 * 基于 TS 对 axios 的封装
 */
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';
import { InternalAxiosRequestConfig } from 'axios';

// 定义接口响应数据的结构
interface ApiResponse<T> {
  code: number;
  message: string;
  data: T;
}

class BaseRequest {
  private axiosInstance: AxiosInstance;

  constructor() {
    this.axiosInstance = axios.create({
      baseURL: 'http://localhost:3000',
      timeout: 1000,
      headers: {
        'Content-Type': 'application/json;charset=utf-8'
      }
    });
    // 请求拦截器
    this.axiosInstance.interceptors.request.use(
      (config: InternalAxiosRequestConfig) => {
        // 在请求发送之前做些什么
        // 可以在此处添加认证信息等
        return config;
      },
      (error: AxiosError) => {
        // 对请求错误做些什么
        return Promise.reject(error);
      }
    );

    // 响应拦截器
    this.axiosInstance.interceptors.response.use(
      (response: AxiosResponse) => {
        // 对响应数据做点什么
        // 这里假设 API 返回的数据结构为 { code: number, message: string, data: any }
        const apiResponse: ApiResponse<any> = response.data;
        if (apiResponse.code === 200) {
          // 如果响应 code 为 200，表示请求成功
          return apiResponse.data;
        } else {
          // 如果响应 code 不为 200，表示请求失败，抛出错误
          return Promise.reject(new Error(apiResponse.message));
        }
      },
      (error: AxiosError) => {
        // 对响应错误做点什么
        if (error.response) {
          // 请求已发出，但服务器响应的状态码不在 2xx 范围内
          console.error('Response error:', error.response.status);
        } else if (error.request) {
          // 请求已发出，但没有收到响应
          console.error('Request error:', error.request);
        } else {
          // 在设置请求时触发错误
          console.error('Request setup error:', error.message);
        }
        return Promise.reject(error);
      }
    );
  }

  async GET(url: string, params?: any) {
    return await this.request('GET', url, params);
  }

  async POST(url: string, data: any) {
    return await this.request('POST', url, data);
  }

  async PUT(url: string, data: any) {
    return await this.request('PUT', url, data);
  }

  async DELETE(url: string, params?: any) {
    return await this.request('DELETE', url, params);
  }

  async request(method: string, url: string, data: any) {
    try {
      const response = await this.axiosInstance.request({ method, url, data });
      const res = response.data;
      return res;
    } catch (error) {
      console.error('request error:', error);
      throw error;
    }
  }
}

export default BaseRequest;
